Parallel to Serie (74HC165)

Contenido

Como usar modulos Parallel to Serie (74HC165) para aumentar el numero de puertos de entrada.

Datasheet 74HC165

Pines 74HC165:

El modulo 74HC165 nos permite convertir multiples entradas (en paralelo) en una señal en serie.

Usamos principalmente 3 pines del 74HC165 para controlarlo.

Por lo tanto el funcionamiento es: usamos Latch para generar un snapshot de las entradas conectadas a los pines (A-H), generamos una señal de reloj Clock para hacer que el modulo envíe los bits del snapshot a traves del pin QH, recibimos esa información en el microcontrolador usando el protocolo SPI.

Circuito

NOTA: En las entradas conectadas al modulo 74HC165 ponemos una resistencia de 10K ohm como pull-down.

#include <avr/io.h>
#include <util/delay.h>

void SPI_Init() {
    DDRB |= (1 << PB5) | (1 << PB3) | (1 << PB2);
    DDRB &= ~(1 << PB4);

    // Habilita SPI, Modo Maestro, Velocidad fck/16
    SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
}

uint8_t read_74HC165() {
    uint8_t data;

    // Pulso en PL para cargar los datos paralelos
    PORTB &= ~(1 << PB2);
    //_delay_us(1); // Opcional? descomentar en caso de que el latch no funcione
    PORTB |= (1 << PB2);

    // Iniciar transmisión SPI (enviamos dummy data para recibir)
    // En este caso lo único que necesitamos aquí es generar los pulsos de reloj para recibir la informacion.
    SPDR = 0x00;

    // Esperar a que termine la transferencia
    while(!(SPSR & (1 << SPIF)));

    data = SPDR;

    return data;
}

int main(void) {
    SPI_Init();

    //PC0 y PC1 como salidas para los leds
    DDRC |= (1 << PC0) | (1 << PC1);

    while(1) {
        PORTC = read_74HC165();
    }
}
Modulos en cascada

Si queremos podemos conectar varios modulos 74HC165 en cascada, de manera que la información de uno pasa a traves del otro, solo tenemos que conectar la salida Q7 de un modulo a la entrada DS del otro, la salida (Q7) del último módulo irá conectada al microcontrolador, de esta manera podemos leer 16 entradas en vez de 8, a la hora de hacer la lectura a traves del SPI tendremos que leer 2 bytes en lugar de 1 para leer los dos módulos.

#include <avr/io.h>
#include <util/delay.h>

void SPI_Init() {
    DDRB |= (1 << PB5) | (1 << PB3) | (1 << PB2);
    DDRB &= ~(1 << PB4);

    // Habilita SPI, Modo Maestro, Velocidad fck/16
    SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
}

uint16_t read_74HC165() {
    uint16_t data;

    // Pulso en PL para cargar los datos paralelos
    PORTB &= ~(1 << PB2);
    //_delay_us(1); // Opcional? descomentar en caso de que el latch no funcione
    PORTB |= (1 << PB2);

    // Iniciar transmisión SPI (enviamos dummy data para recibir)
    // En este caso lo único que necesitamos aquí es generar los pulsos de reloj para recibir la informacion.
    SPDR = 0x00;

    // Esperar a que termine la transferencia
    while(!(SPSR & (1 << SPIF)));

    data = SPDR;

    // Leemos el segundo byte
    SPDR = 0x00;

    while(!(SPSR & (1 << SPIF)));
    data = data | (uint16_t)SPDR << 8;

    return data;
}

int main(void) {
    SPI_Init();

    //PC0 y PC1 como salidas para los leds
    DDRC |= (1 << PC0);
    DDRD |= (1 << PD0);

    uint16_t inputs_status;

    while(1) {
        inputs_status = read_74HC165();
        PORTC = (uint8_t) inputs_status;
        PORTD = (uint8_t) (inputs_status>>8);
    }
}
Tags

AVR | Parallel | Serie | 74HC165